package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.enums.PaymentWay;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.CartInfoMapper;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.product.client.ProductClientFeign;
import com.atguigu.gmall.rabbit.constants.MQConst;
import com.atguigu.gmall.rabbit.util.RabbitService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: lx
 * @Time: 15:02
 * @Description:
 */
@Service
public class OrderInfoServiceImpl implements OrderInfoService {

    @Value("${ware.url}")
    private String wareUrl;
    @Autowired
    private ProductClientFeign productClientFeign;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CartInfoMapper cartInfoMapper;

    //连接库存管理系统
    @Override
    public boolean hasStock(OrderDetail orderDetail) {
        //HttpClient
        return "1".equals(HttpClientUtil.doGet(wareUrl +
                "/hasStock?skuId=" + orderDetail.getSkuId()
                + "&num=" + orderDetail.getSkuNum()));
    }

    @Autowired
    private RabbitService rabbitService;

    //保存订单信息
    @Override
    public Long saveOrderInfo(OrderInfo orderInfo) {
        //1:订单表

        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //订单交易编号  （支付宝之间 交易唯一主键）
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + "" +
                new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);

        //创建时间
        Date curDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR, 2);
        Date expireTime = calendar.getTime();
        orderInfo.setCreateTime(curDate);
        orderInfo.setExpireTime(expireTime);
        //进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());

        StringBuilder sb = new StringBuilder();

        //2:订单详情表
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            sb.append(orderDetail.getSkuName() + " ");
            //真实价格
            BigDecimal price = productClientFeign.getPrice(orderDetail.getSkuId());
            orderDetail.setOrderPrice(price);
        }
        if (sb.length() > 100) {
            orderInfo.setTradeBody(sb.toString().substring(0, 100));
        } else {
            orderInfo.setTradeBody(sb.toString());
        }
        //总金额（记算）
        orderInfo.sumTotalAmount();
        //保存订单 返回值ID
        orderInfoMapper.insert(orderInfo);


        QueryWrapper<CartInfo> wrapper = new QueryWrapper<CartInfo>();

        for (OrderDetail orderDetail : orderDetailList) {
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
            wrapper.eq("sku_id", orderDetail.getSkuId())
                    .eq("user_id", orderInfo.getUserId());
            wrapper.or();
        }
        //3:删除购物车中提交了订单的商品
        // delete from 表 where  (sku_id = 10 and  user_id = 3 ) or (sku_id = 14 and  user_id = 3 )
        //cartInfoMapper.delete(wrapper);
        //4:MQ 延迟消息  开始计时   2小时 之后
        //rabbitService.sendDeadMessage(MQConst.EXCHANGE_DIRECT_ORDER_CANCEL
        //,MQConst.ROUTING_ORDER_CANCEL1,orderInfo.getId(),10);

        return orderInfo.getId();
    }

    //取消订单
    @Override
    public void cancelOrderByOrderId(Long orderId) {
        //幂等性问题
        //1:查询订单状态 是否已经取消  2小时之后 二维码肯定失败
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.name())) {
            //2:如果尚未取消 取消订单
            orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            orderInfo.setExpireTime(new Date());
            orderInfoMapper.updateById(orderInfo);

            //关闭支付宝   二维码失效前已经扫码了 关闭掉   关闭无此订单
            //response 响应 关闭失败  关闭成功
        }
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }

    //更新订单的状态  已经支付的状态
    @Override
    public void updateOrderStatus(Long orderId) {
        //幂待性问题
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        //判断是否为未支付
        if (OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())) {
            //改成已支付
            orderInfo.setOrderStatus(OrderStatus.PAID.name());
            //进度状态
            orderInfo.setProcessStatus(ProcessStatus.PAID.name());
            //更新订单的状态
            orderInfoMapper.updateById(orderInfo);
            //发消息 减库存
            rabbitService.sendMessage(MQConst.EXCHANGE_DIRECT_WARE_STOCK,
                    MQConst.ROUTING_WARE_STOCK,
                    JSONObject.toJSONString(initWareOrder(orderId)));

        }
    }

    //查询订单及详情相关
    public OrderInfo getOrderInfoAndOrderDetail(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (null != orderInfo) {
            orderInfo.setOrderDetailList(orderDetailMapper.selectList(new QueryWrapper<OrderDetail>()
                    .eq("order_id", orderId)));
        }
        return orderInfo;
    }

    //重载方法
    public Map<String, Object> initWareOrder(Long orderId) {
        //1:查询订单及订单详情
        OrderInfo orderInfo = getOrderInfoAndOrderDetail(orderId);
        //2:组合发送的消息内容
        Map<String, Object> result = initWareOrder(orderInfo);
        return result;
    }


    //订单微服务中 开始折单
    @Override
    public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
        // wareSkuMap  条件
        //[{"wareId":"1","skuIds":["1"]},{"wareId":"2","skuIds":["10","13"]}]
        List<Map> wareSkuMapList = JSONObject.parseArray(wareSkuMap, Map.class);
        //1:原始订单 为基本 折成多个子订单
        OrderInfo originOrderInfo = getOrderInfoAndOrderDetail(orderId);
        List<OrderDetail> originOrderDetailList = originOrderInfo.getOrderDetailList();
        //  OrderInfo 订单主表  14(一个）  OrderDetail订单详情表  3条    skuId: 10 13 1
        /////////////////////////////////////////////////////////
        //  OrderInfo 订单主表  15      OrderDetail订单详情表  1条 skuID:1
        //  OrderInfo 订单主表  16      OrderDetail订单详情表  2条 skuID: 10 13
        List<OrderInfo> subOrderInfoList = new ArrayList<>();
        for (Map wareSku : wareSkuMapList) {
            //子订单主表
            OrderInfo subOrderInfo = new OrderInfo();
            BeanUtils.copyProperties(originOrderInfo,subOrderInfo);
            //清除父订单的ID
            subOrderInfo.setId(null);
            //当前子订单的父订单ID
            subOrderInfo.setParentOrderId(originOrderInfo.getId());
            //仓库的ID
            subOrderInfo.setWareId(String.valueOf(wareSku.get("wareId")));
            //子订单详情集合
            List<OrderDetail> subOrderDetailList = new ArrayList<>();

            List<Long> orderDetailIds = new ArrayList<>();

            for (OrderDetail originOrderDetail : originOrderDetailList) {
                List<String> skuIdList = (List<String>) wareSku.get("skuIds");
                if (skuIdList.contains(originOrderDetail.getSkuId())) {
                    //进入if 找到对应仓库   2号   2号
                    orderDetailIds.add(originOrderDetail.getId());
                    //追加进来
                    subOrderDetailList.add(originOrderDetail);
                }
            }
            //子订单主表 设置子订单详情表集合
            subOrderInfo.setOrderDetailList(subOrderDetailList);
            //计算子订单的总金额
            subOrderInfo.sumTotalAmount();
            //保存
            saveOrderInfo(subOrderInfo,orderDetailIds);

            //折单 后的多个子订单主表及子订单详情集合）
            subOrderInfoList.add(subOrderInfo);
        }
        //更新原始订单的订单状态为已折单  进度状态为已折单
        updateOrderStatus(orderId, ProcessStatus.SPLIT);
        //返回值  List<OrderInfo>  OrderInfo  OrderDetailList
        return subOrderInfoList;
    }
    //更新原始订单的订单状态为已折单  进度状态为已折单
    public void updateOrderStatus(Long orderId,ProcessStatus processStatus){
        OrderInfo orderInfo = getOrderInfo(orderId);
        orderInfo.setOrderStatus(processStatus.getOrderStatus().name());
        orderInfo.setProcessStatus(processStatus.name());
        orderInfoMapper.updateById(orderInfo);
    }
    public void saveOrderInfo(OrderInfo subOrderInfo,List<Long> orderDetailIds){

        orderInfoMapper.insert(subOrderInfo);
        //保存子订单详情表集合  update order_detail set order_id = 15 where id in (33,34)
        OrderDetail subOrderDetail = new OrderDetail();
        subOrderDetail.setOrderId(subOrderInfo.getId());
        orderDetailMapper.update(subOrderDetail,
                new QueryWrapper<OrderDetail>().in("id",orderDetailIds));
    }


    //发消息给库存系统 减库存的时候 组合发送的消息内容
    public Map<String, Object> initWareOrder(OrderInfo orderInfo) {
        Map<String, Object> result = new HashMap<>();
        //订单相关信息
        result.put("orderId", orderInfo.getId());
        result.put("consignee", orderInfo.getConsignee());
        result.put("consigneeTel", orderInfo.getConsigneeTel());
        result.put("orderComment", orderInfo.getOrderComment());
        result.put("orderBody", orderInfo.getTradeBody());
        result.put("deliveryAddress", orderInfo.getDeliveryAddress());
        result.put("paymentWay", "2");
        result.put("wareId", orderInfo.getWareId());
        //订单详情信息
        List<Map> details = new ArrayList<>();
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        orderDetailList.forEach(orderDetail -> {
            Map map = new HashMap();
            map.put("skuId", orderDetail.getSkuId());
            map.put("skuNum", orderDetail.getSkuNum());
            map.put("skuName", orderDetail.getSkuName());
            details.add(map);
        });
        //将订单详情保存在订单的Map中
        result.put("details", details);
        return result;
    }

}
